/*
 * Project: Hell Watch
 * Author: pajoke
 * Copyright: (C) 2014 Hell Prototypes
 * License: GNU GPL v3 (see License.txt)
 * Web: http://www.hellprototypes.com
 */

#include <avr/io.h>
#include <avr/eeprom.h>
#include <avr/power.h>
#include <util/delay.h>
#include "common.h"
#include "devices/battery.h"
#include "devices/buttons.h"
#include "millis/millis.h"

static const byte battery_log[BAT_LOG_SIZE] EEMEM;

static uint voltage;

extern void short_delay(void);

#define START_BAT_ADC()		setbit(ADCA.CH0.CTRL, 7)
#define WAIT_BAT_CONVERT()	do{ while(!testbit(ADCA.CH0.INTFLAGS,0)); ADCA.CH0.INTFLAGS = 1;}while(0)

void battery_init()
{
	ADCA.CH0.MUXCTRL  = 0x00;	// Channel 0 input: ADC0 pin
	ADCA.CH0.CTRL	  = 0x01;	// Single-ended positive input signal

	PORTA.PIN0CTRL	  = 0x07;  //Digital input buffer disabled
}

// Update voltage
void battery_update()
{
	byte old_ref = ADCA.REFCTRL;
	uint last_voltage = voltage;

	ADCA.REFCTRL	  = 0x02;	// REF= 1V

	while(1) {
		START_BAT_ADC();
		WAIT_BAT_CONVERT();
		voltage = ((ulong)ADCA.CH0.RESL * 4900) / 256 - 245;//0.05*4900 = 245
		if((last_voltage - voltage) <= 100 ) {
			break;
		}
		last_voltage = voltage;
		short_delay();
	}
	if(voltage < 3100) {
		set_pwr_down();
	}
	ADCA.REFCTRL = old_ref;
}

// Get voltage
uint battery_voltage()
{
	return voltage;
}

void battery_log_update(void)
{
	battery_update();
	uint vol_16 = (battery_voltage() * 2)/100;
	byte vol = (byte)vol_16;// 0 : 0V, 84: 4200mV, 1 step : 500mv
	byte current;
	byte index;

	for(index=0; index<BAT_LOG_SIZE; index++) {
		eeprom_read_block(&current, &battery_log[index], 1);
		if(current & 0x80) {
			break;
		}
	}
	if((index < BAT_LOG_SIZE) && (current != 0xFF)) {
		current &= 0x7F;
		eeprom_update_block(&current, (byte *)&battery_log[index], 1);
		index++;
	}
	if(index >= BAT_LOG_SIZE) {
		index = 0;
	}
	current = 0x80 | (byte)vol;
	eeprom_update_block(&current, (byte *)&battery_log[index], 1);
}

bool battery_get_log(byte start, byte len, byte *read_buffer)
{
	if(start + len > BAT_LOG_SIZE) {
		return false;
	}

	eeprom_read_block(read_buffer, &battery_log[start], len);

	for(byte index=0; index<BAT_LOG_SIZE; index++) {
		if(read_buffer[index] == 0xff) {
			read_buffer[index] = 0;//0V
		}
	}

	return true;
}

